by Pete Gontier, © 1999 Apple Computer, Inc., All Rights Reserved.
Introduction
BackScrap is a system extension which detects and draws attention to calls to the Scrap Manager (which helps applications manage what users know as "the clipboard") made from within the context of an application which is in the background. Scrap Manager, for all intents and purposes, does not listen to background applications and produces benignly incorrect data -- in other words, it does nothing useful. Generally speaking, applications do not make system calls with the intent of nothing useful happening, so such calls are probably signs of unexpected and/or untested code.Messages
BackScrap knows about six Scrap Manager functions: PutScrap, InfoScrap, UnloadScrap, LoadScrap, GetScrap, and ZeroScrap. When BackScrap detects a bogus call to one of these functions, it passes a descriptive string to DebugStr. The string typically shows up in a debugger. If there is no debugger installed, this call to DebugStr will cause a crash, so don't install BackScrap on a system without a debugger. The string looks like this:
_PutScrap called from app in background.Meanings
When BackScrap displays a message, it usually means the caller doesn't realize it is in the background. This may or may not be significant, because some callers don't behave poorly as a result of getting the benign data produced by Scrap Manager as described above. Things get more interesting, however, when the caller expects Scrap Manager to work and Scrap Manager doesn't work. The most common case of this problem is when an application defers processing a suspend event which has its scrap translation bit set. Once an application receives a suspend event, it must assume the next call to Event Manager will cause the application to be switched into the background. The application must convert its private scrap, if any, to the public scrap before making its next Event Manager call. Relevant Event Manager calls include not only WaitNextEvent, GetNextEvent, and EventAvail, but also any routine which calls these Event Manager routines, such as ModalDialog, which calls WaitNextEvent, and StandardGetFile, which calls ModalDialog. The user-visible effects of an application failing to immediately convert its private scrap to the public scrap are that the data in the private scrap cannot be pasted into other applications as expected.Installation and Removal
To install BackScrap, drop it onto a closed System Folder icon. When asked whether you want the file to be stored in the Extensions folder, say yes. Restart to activate BackScrap.To remove BackScrap, open the Extensions folder in the System Folder. Find BackScrap in the Extensions folder and drag it out to the desktop or the Trash. Alternatively, use the Extensions Manager control panel to disable BackScrap. Restart to deactivate BackScrap.
Theory of Operation
BackScrap patches PutScrap, InfoScrap, UnloadScrap, LoadScrap, GetScrap, and ZeroScrap. Each patch calls through to the previous implementation of its trap. After the previous implementation returns, the patches each call a function which determines whether the current application context is frontmost. If not, this function decides which trap has been called and passes an appropriate string to DebugStr.It's important to note that the source code for BackScrap is deceptively simple. It so happens that all Scrap Manager traps are simple stack-based Toolbox traps. This makes them very easy to patch in a high level language like C or Pascal. Other traps are not so easy, so if you need to patch OS traps or some of the more complicated Toolbox traps like Standard File (aka _PACK3), be prepared to write some assembly code. Also, be aware that because the Scrap Manager is generally not called in a performance intensive way, I chose to write BackScrap entirely in 68K code. If you are patching a trap which is called often or repeatedly, especially if many callers are PowerPC code, you are going to want to compile patches into PowerPC code and make routine descriptors for them.
Quasi-interesting Factoids
Print Monitor calls InfoScrap, then UnloadScrap, every time it starts up, even when it is in the background. It's debatable whether this is a bug, because it's likely that Print Monitor is just trying to make sure its heap has the most memory possible before it starts to spool print jobs. The authors may not have cared much whether InfoScrap and UnloadScrap had any effect because Print Monitor was going to try to spool print jobs regardless and fail only if it actually ran out of memory. There may be other applications which have similar behavior.